package com.yst.webplugin.fieldhandler;

import com.yst.spring.context.SpringContext;
import com.yst.web.utils.ClassUtils;
import com.yst.webplugin.additional.ResultProcessor;
import com.yst.webplugin.additional.mask.MaskConfigUtil;
import com.yst.webplugin.additional.transform.TransformConfigUtil;
import com.yst.webplugin.annotation.HttpInfo;
import com.yst.webplugin.annotation.Query;
import com.yst.webplugin.annotation.QuerySingleRow;
import com.yst.webplugin.util.ParamUtils;
import lombok.SneakyThrows;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class QuerySingleRowHandler implements IFieldHandler{
    @Override
    public boolean accept(Field field) {
        return Objects.nonNull(field.getAnnotation(QuerySingleRow.class));
    }

    @SneakyThrows
    @Override
    public void handle(Field field, HttpInfo httpInfo) {
        QuerySingleRow query=field.getAnnotation(QuerySingleRow.class);
        String sqlOrName= query.sqlOrSqlName();
        sqlOrName= sqlOrName.isEmpty() ? query.name() : sqlOrName;
        sqlOrName= sqlOrName.isEmpty() ?field.getName():sqlOrName;
        SqlToyLazyDao sqlToyLazyDao= SpringContext.getContext().getBean(SqlToyLazyDao.class);

        if (ClassUtils.isAssignableFrom(field.getType(), query.modelClass())) {

            Map<String, Object> params = httpInfo.getBodyAs(HashMap.class);

            ParamUtils.checkParams(params, query.validClass(), query.validClassGroup());

            List<?> data = sqlToyLazyDao.findBySql(sqlOrName, params, query.modelClass());
            ResultProcessor resultProcessor = new ResultProcessor()
                    .addAllFieldMaskConfig(MaskConfigUtil.fromField(field))
                    .addAllTransformConfig(TransformConfigUtil.fromField(field))
                    .addAllTransformConfig(TransformConfigUtil.fromClass(query.modelClass()))
                    .disableField(query.disabledFields());

            resultProcessor.deepProcess(data, query.modelClass());
            if (!data.isEmpty()) {
                httpInfo.writeResult(data.get(0));
            }
            else {
                httpInfo.writeResult(null);
            }
            return;
        }

        throw new RuntimeException(String.format("not supports type of the result:%s",
                field.getType().getName()));
    }
}
